#pragma once

#include "event_loop.h"
#include "tcp_connection.h"
#include "tcp_acceptor.h"
#include <map>

namespace uvpp
{
	using OnConnectionStatusCallback = std::function<void (std::weak_ptr<TCPConnection>)>;
	
	class TCPServer
	{
	using ConnectionMap = std::map <std::string, TCPConnectionPtr>;

	public:
		TCPServer(EventLoop* loop, bool noDelay = true);
		virtual ~TCPServer();

		int bindAndListen(InetAddress& address);
		void close();

		TCPConnectionPtr getConnection(const std::string& name);

		void setMessageCallback(OnMessageCallback callback);
		void setNewConnectionCallback(OnConnectionStatusCallback callback);
		void setCloseConnectionCallback(OnConnectionStatusCallback callback);
		TCPConnectionPtr getConnection(const std::string& name);
		void closeConnection(std::string& name);
	private:
		void onAccept(EventLoop* loop, TCPPtr client);
		void addConnection(std::string& name, TCPConnectionPtr connection);
		void removeConnection(std::string& name);
	protected:
		EventLoop* _loop;

	private:
		ConnectionMap _connectionMap;
		bool _noDelay;
		std::shared_ptr<TCPAcceptor> _acceptor;

		OnConnectionStatusCallback _newConnectionCallback;
		OnConnectionStatusCallback _closeConnecitonCallback;
		OnMessageCallback _onMessageCallback;
	};
}
